package yanyan.com.tochar.funsactivity;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.files.DialogFileChooserExtKt;
import com.gs.buluo.common.widget.LoadingDialog;
import com.hjq.permissions.Permission;

import java.io.File;
import java.io.IOException;

import androidx.annotation.Nullable;
import io.microshow.rxffmpeg.RxFFmpegInvoke;
import io.microshow.rxffmpeg.RxFFmpegSubscriber;
import yanyan.com.tochar.R;
import yanyan.com.tochar.utils.CoreUtil;
import yanyan.com.tochar.utils.EmptyUtils;
import yanyan.com.tochar.utils.FileUtil;
import yanyan.com.tochar.utils.PermissionsUtil;
import yanyan.com.tochar.utils.PictureSelectUtil;
import yanyan.com.tochar.utils.ToastUtil;

import static android.os.Environment.getExternalStorageDirectory;

/**
 * 声音倒放
 */
public class FunsVoiceUpendActivity extends Activity {

    private MediaRecorder mediaRecorder;//创建一个空的MediaRecorder对象
    private Button button_record;
    private Button button_rever1;
    private TextView textView, stateText;
    private String path = "";

    private EditText resFilepathEd, selectFilePath;
    private TextView selectRecord, selectFile;

    private boolean isRecord = false;  //是否在录音
    private String recordFile = "";   //录音路径
    private String reRecordFile = ""; //倒放声音文件路径
    private String selectFilePathStr = "";

    private boolean type = true;

    private LinearLayout voiceLayout, fileLayout;
    private MediaPlayer mPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_funs_voice_upend);
        path = PictureSelectUtil.getCachePath(this);
        textView = findViewById(R.id.voice_upend_text);
        resFilepathEd = findViewById(R.id.voice_upend_res_file_path);
        selectRecord = findViewById(R.id.voice_upend_select_record);
        selectFile = findViewById(R.id.voice_upend_select_file);
        stateText = findViewById(R.id.voice_upend_state);
        selectFilePath = findViewById(R.id.voice_upend_select_file_path);
        voiceLayout = findViewById(R.id.voice_upend_voice_layout);
        fileLayout = findViewById(R.id.voice_upend_file_layout);

        mPlayer = new MediaPlayer();
        //申请权限
        PermissionsUtil.authorization(new String[]{Permission.RECORD_AUDIO}, this);
        //统计各功能
        CoreUtil.statisticalFuns(this, "funs_voice_upend");
    }


    /**
     * 开始录音的方法
     */
    public void startRecord() {
        //获取录音文件路径
        String path = getRecordFilePath();//获取录音文件路径
        if (!"".equals(path)) {
            stateText.setText("停止录音");
            mediaRecorder = new MediaRecorder();//实例化MediaRecorder
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            //设置记录的媒体文件的输出转换格式。
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            // 设置音频记录的编码格式。
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            if (Build.VERSION.SDK_INT >= 10) {
                mediaRecorder.setAudioSamplingRate(44100);
                mediaRecorder.setAudioEncodingBitRate(96000);
            } else {
                // older version of Android, use crappy sounding voice codec
                mediaRecorder.setAudioSamplingRate(8000);
                mediaRecorder.setAudioEncodingBitRate(12200);
            }
            mediaRecorder.setOutputFile(path);//设置输出路径
        }
        //文件录制错误监听
        mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {

            @Override
            public void onError(MediaRecorder arg0, int arg1, int arg2) {
                if (mediaRecorder != null) {
                    //解除资源与mediaRecorder的赋值关系,让资源可以为其他程序利用
                    mediaRecorder.release();
                    Toast.makeText(FunsVoiceUpendActivity.this, "record error", Toast.LENGTH_SHORT).show();
                }
            }
        });
        try {
            mediaRecorder.prepare();//准备
            mediaRecorder.start();//开始录音

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止录音的方法
     */
    public void stopRecord() {

        if (mediaRecorder != null) {
            stateText.setText("开始录音");
            mediaRecorder.stop();//停止录音
            mediaRecorder.release();//释放资源
        }
        String inPath = path + "01.mp3";
        recordFile = inPath;
    }


    /**
     * 清理文件
     */
    public void clear() {
        try {
            reRecordFile = "";
            recordFile = "";
            File f = new File(path + "01.mp3");
            File f2 = new File(path + "02.mp3");
            if (f.exists()) {
                f.delete();
            }
            if (f2.exists()) {
                f2.delete();
            }
        } catch (Exception e) {
            ToastUtil.showLongToast(this, e.getMessage());
        }
    }

    /**
     * 获取录音文件的路径
     *
     * @return
     */
    public String getRecordFilePath() {
        String filePath = path;//声明文件路径
        String sdCardPath = path;
        File dirFile = new File(sdCardPath);//自定义的录音文件File文件对象
        if (!dirFile.exists()) {
            dirFile.mkdir();//不存在创建文件夹
        }
        try {
            //创建一个前缀为test后缀为.amr的录音文件，使用createTempFile方法来创建是为了避免文件冲突
            filePath = sdCardPath + "01.mp3";
            recordFile = filePath;
            File file = new File(filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return filePath;//返回录音文件路径
    }

    //播放音频
    private void starPplay(String FileName) {
        try {
            if (mPlayer.isPlaying()) {
                mPlayer.stop();
            }
            mPlayer.reset();
            mPlayer.setDataSource(FileName);
            mPlayer.prepare();
            mPlayer.start();
        } catch (IOException e) {
            Log.e("test", "播放失败");
            Toast.makeText(FunsVoiceUpendActivity.this, "先录个音吧？", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 读取录音文件的时间
     *
     * @return
     */
    private String timePlay() {

        try {
            if (mPlayer.isPlaying()) {
                mPlayer.stop();
            }
            mPlayer.reset();
            mPlayer.setDataSource(path + "01.mp3");
            mPlayer.prepare();
            Float a = (float) mPlayer.getDuration() / 1000;
            return a.toString() + "s";
        } catch (IOException e) {

        }
        return "无录音";

    }


    /**
     * 选择模式逻辑
     *
     * @param view
     */
    public void selectModel(View view) {
        if (isRecord) {
            ToastUtil.showLongToast(this, "正在录音");
            return;
        }
        int id = view.getId();
        if (id == R.id.voice_upend_select_record) {
            selectRecord.setBackgroundResource(R.drawable.bg_blue_left);
            fileLayout.setVisibility(View.GONE);
            voiceLayout.setVisibility(View.VISIBLE);
            selectFile.setBackground(null);
            type = true;
        } else {
            selectRecord.setBackground(null);
            selectFile.setBackgroundResource(R.drawable.bg_blue_right);
            fileLayout.setVisibility(View.VISIBLE);
            voiceLayout.setVisibility(View.GONE);
            type = false;
        }
    }

    /**
     * 录音及停止
     *
     * @param view
     */
    public void startAndStopRecord(View view) {
        if (!isRecord) {
            this.clear();
            textView.setText("录音中");
            //开始录音
            startRecord();
            isRecord = true;
        } else {
            //停止录音
            stopRecord();
            textView.setText(timePlay());
            isRecord = false;
        }
    }

    /**
     * 播放
     *
     * @param view
     */
    public void onPlay(View view) {
        if (!type) {
            recordFile = selectFilePath.getText().toString();
        }
        if (isRecord) {
            ToastUtil.showLongToast(this, "正在录音");
            return;
        }
        if (EmptyUtils.isNotEmpty(recordFile)) {
            starPplay(recordFile);
        } else {
            ToastUtil.showLongToast(this, "没有音频，请录个音或者选择声音文件");
        }
    }

    /**
     * 倒放
     *
     * @param view
     */
    public void onRePlay(View view) {
        if (isRecord) {
            ToastUtil.showLongToast(this, "正在录音");
            return;
        }
        if (!type) {
            recordFile = selectFilePath.getText().toString();
        }
        if (EmptyUtils.isNotEmpty(recordFile)) {
            String outFile = path + "02.mp3";
            if (EmptyUtils.isEmpty(reRecordFile)) {
                voiceUpend(recordFile, outFile, new OnReVoiceState() {
                    @Override
                    public void finsh() {
                        starPplay(reRecordFile);
                    }
                });
                reRecordFile = outFile;
            } else {
                starPplay(reRecordFile);
            }
        } else {
            ToastUtil.showLongToast(this, "没有音频，请录个音或者选择声音文件");
        }
    }

    /**
     * 保存
     *
     * @param view
     */
    public void upendVoiceSaven(View view) {
        if (isRecord) {
            ToastUtil.showLongToast(this, "正在录音");
            return;
        }
        if (EmptyUtils.isNotEmpty(recordFile)) {
            File file=new File(recordFile);
            if (EmptyUtils.isEmpty(reRecordFile)) {
                String outFile = path + "02.mp3";
                voiceUpend(recordFile, outFile, new OnReVoiceState() {
                    @Override
                    public void finsh() {
                        String s = FileUtil.savenMp3ToSd(reRecordFile, file.getName(),FunsVoiceUpendActivity.this);
                        if (CoreUtil.isAndroidQ()) {

                        } else {
                            ToastUtil.showLongToast(FunsVoiceUpendActivity.this, "已保存到：" + s);
                        }

                    }
                });
                reRecordFile = outFile;
            } else {
                String s = FileUtil.savenMp3ToSd(reRecordFile, file.getName(), FunsVoiceUpendActivity.this);
                if (CoreUtil.isAndroidQ()) {

                } else {
                    ToastUtil.showLongToast(FunsVoiceUpendActivity.this, "已保存到：" + s);
                }
            }
        } else {
            ToastUtil.showLongToast(this, "没有音频，请录个音或者选择声音文件");
        }

    }

    /**
     * 选择声音文件
     *
     * @param view
     */
    public void selectMp3File(View view) {
        clear();
        selectFile();
    }

    public void selectFile() {
        MaterialDialog dialog = new MaterialDialog(this, MaterialDialog.getDEFAULT_BEHAVIOR());
        dialog.title(R.string.selectFile, "选择音频文件");
        if (CoreUtil.isAndroidQ()) {
            selectFile("");
            return;
        }

        DialogFileChooserExtKt.fileChooser(dialog, getExternalStorageDirectory(), file -> {
                    return (file.getName().endsWith(""));
                },
                true, R.string.files_folder_hint, false, null,
                (materialDialog, file) -> {
                    Toast.makeText(this, file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
                    selectFilePathStr = file.getAbsolutePath();
                    return null;
                });


        dialog.positiveButton(R.string.selectFile, null, materialDialog -> {
            if (EmptyUtils.isNotEmpty(selectFilePathStr)) {
                if(selectFilePathStr.endsWith("mp3")){
                    selectFilePath.setText(selectFilePathStr);
                }else {
                    selectFilePathStr=null;
                    ToastUtil.showLongToast(this,"请选择mp3格式的文件");
                }

            }else {
                Toast.makeText(this, "点击了确定111111111111111", Toast.LENGTH_SHORT).show();
            }

            return null;
        });


        dialog.negativeButton(android.R.string.cancel, null, materialDialog -> {
            selectFilePathStr = "null";
            return null;
        });
        dialog.show();
    }

    public void selectFile(String isQ) {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("audio/mp3");
        this.startActivityForResult(intent, 3306);
    }


    // 获取文件的真实路径
    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data == null) {
            // 用户未选择任何文件，直接返回
            return;
        }
        Uri uri = data.getData(); // 获取用户选择文件的URI
        // 通过ContentProvider查询文件路径
        ContentResolver resolver = this.getContentResolver();
        Cursor cursor = resolver.query(uri, null, null, null, null);
        if (cursor == null) {
            // 未查询到，说明为普通文件，可直接通过URI获取文件路径
            String path = uri.getPath();
            recordFile = path;
            selectFilePath.setText(path);
            return;
        }
        if (cursor.moveToFirst()) {
            // 多媒体文件，从数据库中获取文件的真实路径
            String path = cursor.getString(cursor.getColumnIndex("_data"));
            recordFile = path;
            selectFilePath.setText(path);
        }
        cursor.close();
    }


    /**
     * 声音反转
     *
     * @param inPath
     * @param outPath
     */
    public void voiceUpend(String inPath, String outPath, OnReVoiceState onReVoiceState) {
        //  ffmpeg -i /data/data/com.blbl.Audio/recording/01.mp3 -vf reverse -af areverse -preset superfast /data/data/com.blbl.Audio/recording/02.mp3
        String excuteStr = "ffmpeg -i ";
        excuteStr += inPath;
        excuteStr += " -vf reverse -af areverse -preset superfast ";
        excuteStr += outPath;
        audioRevel(excuteStr, onReVoiceState);
        Log.i("执行代码:", excuteStr);
    }

    public void audioRevel(String text, OnReVoiceState onReVoiceState) {
        LoadingDialog.getInstance().show(FunsVoiceUpendActivity.this, "正在生成", false);//加载
        String[] commands = text.split(" ");
        RxFFmpegInvoke.getInstance().runCommandRxJava(commands).subscribe(new RxFFmpegSubscriber() {
            @Override
            public void onFinish() {
                onReVoiceState.finsh();
                LoadingDialog.getInstance().dismissDialog();

            }

            @Override
            public void onProgress(int progress, long progressTime) {

            }

            @Override
            public void onCancel() {
                LoadingDialog.getInstance().dismissDialog();
            }

            @Override
            public void onError(String message) {
                LoadingDialog.getInstance().dismissDialog();
                ToastUtil.showLongToast(FunsVoiceUpendActivity.this, "错误：" + message);
            }
        });
    }

    public interface OnReVoiceState {
        public void finsh();
    }


}
